/*
 * GStandingsComparator.java
 * Created on 28 déc. 2007
 *
 * Glacéo Internet Platform
 * http://sourceforge.net/projects/chm/
 *
 * Copyright (c) 2005-2007, Jan Janke (VirtualHockey Project)
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.hockeo.vhbase.data.helper;


import java.util.Comparator;

import com.hockeo.vhbase.data.dao.standings.GStandings;

/**
 * Comparator that imposes a sort order specified by a constant of
 * {@link GStandingsSortCriteria} to {@link GStandings} objects.
 *
 * Note: this comparator imposes orderings that are inconsistent with equals.
 *
 * @version $Id$
 * @author jjanke
 */
public class GStandingsComparator implements Comparator<GStandings>
{
  private GStandingsSortCriteria d_sortCriteria;

  /**
   * Creates a new GStandingsComparator.
   *
   * @param sortCriteria the sort criteria to be used by this comparator
   */
  public GStandingsComparator( final GStandingsSortCriteria sortCriteria )
  {
    d_sortCriteria = sortCriteria;
  }

  /*
   * Compares two standings according to the currently set sort criteria.
   */
  public int compare( GStandings s1, GStandings s2 )
  {
    switch ( d_sortCriteria )
    {
      case BY_SEASONS:
        throw new UnsupportedOperationException(
            "Only GArchivedStandings with the archive type ETERNAL can be ordered by the number of seasons." );

      case BY_MATCHES:
      {
        int nCmp;

        nCmp = s2.getNumMatches() - s1.getNumMatches();

        // If the number of matches is the same, we sort by rank (ascending)
        //
        if ( nCmp != 0 )
          return nCmp;

        return s1.getRank() - s2.getRank();
      }

      case BY_GOALS_AGAINST:
        return s2.getNumGoalsAgainst() - s1.getNumGoalsAgainst();

      case BY_GOALS_DIFF:
        return s2.getGoalsDiff() - s1.getGoalsDiff();

      case BY_GOALS_FOR:
        return s2.getNumGoalsFor() - s1.getNumGoalsFor();

      case BY_LOSSES:
        return s2.getNumLosses() - s1.getNumLosses();

      case BY_LOSSES_SHOOTOUT:
        return s2.getNumLossesOT() - s1.getNumLossesOT();

      case FOR_MULTIPLE_ELEMENTS:
      {
        // Ascending order
        //
        int nCmp = s1.getRankType().getPriority() - s2.getRankType().getPriority();
        if ( nCmp != 0 )
          return nCmp;

        // If this point is reached, fall through to BY_POINTS ordering...
        //
      }

      case BY_POINTS:
      {
        int nCmp;

        nCmp = s2.getNumPoints() - s1.getNumPoints();
        if ( nCmp != 0 )
          return nCmp;

        nCmp = s2.getNumWins() - s1.getNumWins();
        if ( nCmp != 0 )
          return nCmp;

        nCmp = s2.getNumWinsOT() - s1.getNumWinsOT();
        if ( nCmp != 0 )
          return nCmp;

        nCmp = s2.getGoalsDiff() - s1.getGoalsDiff();
        if ( nCmp != 0 )
          return nCmp;

        nCmp = s2.getNumGoalsFor() - s1.getNumGoalsFor();
        if ( nCmp != 0 )
          return nCmp;

        return s2.getRemainingGoals().compareTo( s1.getRemainingGoals() );
      }

      case BY_RANK:
        // Ascending order (s2 and s1 reversed)
        //
        return s1.getRank() - s2.getRank();

      case BY_CROSS_ELEMENT_RANK:
        // Ascending order (s2 and s1 reversed)
        //
        return s1.getCrossElementRank() - s2.getCrossElementRank();

      case BY_REMAINING_GOALS:
        return s2.getRemainingGoals().compareTo( s1.getRemainingGoals() );

      case BY_WINS:
        return s2.getNumWins() - s1.getNumWins();

      case BY_WINS_SHOOTOUT:
        return s2.getNumWinsOT() - s1.getNumWinsOT();

      case BY_POINTS_AVG:
        return s2.getPointsPerMatchAvg().compareTo( s1.getPointsPerMatchAvg() );

      case BY_POINTS_PCT:
        return s2.getPointsPercentage().compareTo( s1.getPointsPercentage() );

      default:
        throw new IllegalStateException( "The sort criteria " + d_sortCriteria.name() + " is not supported." );
    }
  }

  /*
   * @see java.lang.Object#equals(java.lang.Object)
   */
  @Override
  public boolean equals( Object obj )
  {
    try
    {
      GStandingsComparator sc = (GStandingsComparator) obj;

      return ( d_sortCriteria == sc.d_sortCriteria );
    }
    catch ( ClassCastException ex )
    {
      return false;
    }
  }
}
